package tool;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;


public class MacroAdapter {
	private Map<String, String> macroTable = new HashMap<String, String>();

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		if (args.length < 3) {
			System.err
					.println("args needs 3 items [inputPath] [outputPath] [macroPath] (optional dataSize)");
			return;
		}

		int dataSize = 0;
		if(args.length >= 4){
			try{
				dataSize = Integer.parseInt(args[3]);
			}catch(NumberFormatException e){
				e.printStackTrace();
			}
		}

		new MacroAdapter(args[0], args[1], args[2], dataSize);
	}

	public MacroAdapter(String inputPath, String outputPath, String macroPath, int dataSize) {
		List<String> macroList = null;
		try {
			macroList = getList(macroPath, 2, 0);
		} catch (IOException e) {
			e.printStackTrace();
			return;
		}
		for (int i = 0; i < macroList.size() / 2; i++) {
			macroTable.put(macroList.get(i * 2), macroList.get(i * 2 + 1));
		}

		File file = new File(inputPath);
		if(file.isDirectory()){
			String[] files = file.list();
			for(String f : files){
				adaptMacro(inputPath + "/" + f, outputPath + "/" + f, dataSize);
			}
		}else{
			adaptMacro(inputPath, outputPath, dataSize);
		}
	}

	private void adaptMacro(String inputPath, String outputPath, int dataSize) {
		List<String> inputList = null;
		List<String> outputList = new ArrayList<String>();
		try {
			inputList = getList(inputPath, 1, dataSize);
			String[] keys = new String[1];
			keys = macroTable.keySet().toArray(keys);

			for (String input : inputList) {
				for (int i = 0; i < keys.length; i++) {
					input = input.replaceAll(" " + keys[i] + " ", " " + macroTable
							.get(keys[i])
							+ " ");
					input = Pattern.compile("^" + keys[i] + " ", Pattern.MULTILINE).matcher(input).replaceAll(macroTable.get(keys[i]) + " ");
				}
				outputList.add(input);
			}

			putList(outputPath, outputList, dataSize);
			System.out.println("macro adapt [" + outputPath + "] ok");
		} catch (IOException e) {
			System.err.println("error occured at [" + inputPath + "] :" + dataSize);
			e.printStackTrace();
		}
	}

	private List<String> getList(String macroPath, int colSize, int dataSize) throws IOException {
		List<String> result = new ArrayList<String>();
		FileInputStream fis = null;
		DataInputStream dis = null;
		try {
			fis = new FileInputStream(macroPath);
			dis = new DataInputStream(fis);

			int dataLen = dataSize;
			if(dataLen <= 0){
				dataLen = dis.readByte();
			}

			for (int i = 0; i < dataLen * colSize; i++) {
				result.add(dis.readUTF());
			}
		} finally {
			try {
				dis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				fis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return result;
	}

	private void putList(String outputPath, List<String> outputList, int dataSize) throws IOException{
		FileOutputStream fos = null;
		DataOutputStream dos = null;

		try{
			fos = new FileOutputStream(outputPath);
			dos = new DataOutputStream(fos);

			if(dataSize <= 0){
				dos.writeByte(outputList.size());
			}

			for(String item : outputList){
				dos.writeUTF(item);
			}
		}finally{
			try {
				dos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}


	}

}
